package com.cjh.common.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cjh.common.config.RedisKey;
import com.cjh.common.dto.*;
import com.cjh.common.entity.*;
import com.cjh.common.enums.StatusEnum;
import com.cjh.common.mapper.*;
import com.cjh.common.response.Result;
import com.cjh.common.service.PermissionService;
import com.cjh.common.service.StoreOrderService;
import com.cjh.common.wxDto.ApplyForRefundDTO;
import com.cjh.common.wxDto.WXStoreOrderDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;


/**
 *
 */
@Service
public class StoreOrderServiceImpl extends ServiceImpl<StoreOrderMapper, StoreOrder>
    implements StoreOrderService{
    @Autowired
    StoreOrderMapper storeOrderMapper;
    @Autowired
    PermissionService permissionService;
    @Autowired
    UserMapper userMapper;
    @Autowired
    OrderStatusMapper orderStatusMapper;
    @Autowired
    StringRedisTemplate stringRedisTemplate;
    @Autowired
    OrderCommodityMapper orderCommodityMapper;
    @Autowired
    CommodityDetailsMapper commodityDetailsMapper;
    @Override
    public Result getPagingStore(StoreOrderPagingDTO storeOrderPagingDTO) {
//        System.out.println(storeOrderPagingDTO);
        Integer size = storeOrderPagingDTO.getSize();
        Integer current = storeOrderPagingDTO.getCurrent();
        Integer start = (current-1)*size;
        String username = storeOrderPagingDTO.getUsername();
        Integer userId = permissionService.isSuperAdministrator(username)?null:userMapper.selectOne(new QueryWrapper<User>().eq("username", username)).getUserId();
        Integer status = storeOrderPagingDTO.getStatus();
        String number = storeOrderPagingDTO.getNumber();
        Date startTime = storeOrderPagingDTO.getStartTime();
        Date endTime = storeOrderPagingDTO.getEndTime();
        Integer storeId = storeOrderPagingDTO.getStoreId();
        List<StoreOrderDto> pagingStore = storeOrderMapper.getPagingStore(start, size, userId, status, number, startTime, endTime,storeId);
        PagingDTO<StoreOrderDto> storeOrderDtoPagingDTO = new PagingDTO<>();
        storeOrderDtoPagingDTO.setSize(size);
        storeOrderDtoPagingDTO.setCurrent(current);
        storeOrderDtoPagingDTO.setRecords(pagingStore);
        Integer pagingStoreTotal = storeOrderMapper.getPagingStoreTotal(userId, status, number, startTime, endTime,storeId);
        storeOrderDtoPagingDTO.setTotal(pagingStoreTotal);
        return new Result().setCode(200).setMessage("获取成功！").setData(storeOrderDtoPagingDTO);
    }

    @Override
    public Result getStoreByOrderId(Integer orderId) {
        return new Result().setCode(200).setMessage("获取成功！").setData(storeOrderMapper.getStoreByOrderId(orderId));
    }

    /**
     *
     * @param
     * @param status
     * @return
     *     ToBePrinted(1, " 待打印 "), 用户下单
     *     PartsToBeTaken(2, "代取件"), 打印完成，代取件
     *     ToBeDelivered(3, "待配送"),    打印完成，待配送
     *     TransactionCompletion(4, "交易完成"), 订单完成
     *     RefundInProgress(-1, "退款中"), 用户申请退款
     *     Refunded(-2, "已退款"); 商家同意退款
     */
    public String returnStatusMessage(Integer status){
        switch (status){
            case 1:
                return "用户下单";
            case 2:
                return "打印完成，代取件";
            case 3:
                return "打印完成，待配送";
            case 4:
                return "配送完成";
            case 5:
                return "订单完成";
            case -1:
                return "用户申请退款";
            case -2:
                return "商家同意退款";
            case -3:
                return "商家拒绝退款";
            default:
                return null;
        }
    }

    @Override
    public Result updateOrderRemarksByOrderId(Integer orderId, String merchantRemarks) {
        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setOrderId(orderId);
        storeOrder.setMerchantRemarks(merchantRemarks);
        return new Result().setCode(200).setMessage("修改成功！").setData(storeOrderMapper.updateById(storeOrder));
    }

    @Override
    public Result updateOrderStautsByOrderId(List<UpdateOrderStautsDTO> updateOrderStautsDTOList) {
        for (UpdateOrderStautsDTO u : updateOrderStautsDTOList){
            StoreOrder storeOrder = new StoreOrder();
            storeOrder.setOrderId(u.getOrderId());
            storeOrder.setStatus(StatusEnum.getEnumsByCode(u.getStatus()));
            OrderStatus orderStatus = new OrderStatus();
            orderStatus.setOrderId(u.getOrderId());
            orderStatus.setChangeType(u.getStatus());
            orderStatus.setChangeTime(new Date());
            orderStatus.setChangeMessage(returnStatusMessage(u.getStatus()));
            storeOrderMapper.updateById(storeOrder);
            orderStatusMapper.insert(orderStatus);
        }
        Result result = new Result().setCode(200);
        if(updateOrderStautsDTOList.size() == 1){
            return result.setMessage(returnStatusMessage(updateOrderStautsDTOList.get(0).getStatus()));
        }
        ArrayList<Integer> objects = new ArrayList<>(Arrays.asList(2,3));
        if(objects.contains(updateOrderStautsDTOList.get(0).getStatus())){
            result.setMessage("打印成功");
        }else{
            result.setMessage(returnStatusMessage(updateOrderStautsDTOList.get(0).getStatus()));
        }
        return result;
    }

    @Override
    public Result updateOrderStautsByOrderId1(Integer orderId, Integer status) {
        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setOrderId(orderId);
        storeOrder.setStatus(StatusEnum.getEnumsByCode(status));
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setChangeType(status);
        orderStatus.setChangeTime(new Date());
        orderStatus.setChangeMessage(returnStatusMessage(status));
        storeOrderMapper.updateById(storeOrder);
        orderStatusMapper.insert(orderStatus);
        return new Result().setCode(0).setMessage("操作成功！");
    }

    @Override
    public Result applyForRefund(ApplyForRefundDTO applyForRefundDTO) {
        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setOrderId(applyForRefundDTO.getOrderId());
        storeOrder.setStatus(StatusEnum.RefundInProgress);
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(applyForRefundDTO.getOrderId());
        orderStatus.setChangeType(-1);
        orderStatus.setChangeTime(new Date());
        orderStatus.setChangeMessage(returnStatusMessage(-1)+",原因:"+applyForRefundDTO.getMessage());
        storeOrderMapper.updateById(storeOrder);
        orderStatusMapper.insert(orderStatus);
        return new Result().setCode(0).setMessage("申请退款成功！");
    }

    @Override
    public Result cancelApplicationForRefund(Integer orderId) {
        List<OrderStatus> orderStatuses = orderStatusMapper.selectList(Wrappers.<OrderStatus>lambdaQuery().eq(OrderStatus::getOrderId, orderId));
        orderStatuses.forEach(System.out::println);
        if(orderStatuses.get(orderStatuses.size() - 1).getChangeType() != -1){
            return new Result().setCode(2).setMessage("取消申请退款失败！");
        }
        StoreOrder storeOrder = new StoreOrder();
        storeOrder.setOrderId(orderId);
        Integer changeType = orderStatuses.get(orderStatuses.size() - 2).getChangeType();
        storeOrder.setStatus(StatusEnum.getEnumsByCode(changeType));
        OrderStatus orderStatus = new OrderStatus();
        orderStatus.setOrderId(orderId);
        orderStatus.setChangeType(changeType);
        orderStatus.setChangeTime(new Date());
        orderStatus.setChangeMessage("用户取消申请退款");
        storeOrderMapper.updateById(storeOrder);
        orderStatusMapper.insert(orderStatus);
        return new Result().setCode(0).setMessage("取消申请退款成功！");
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result addOrder(WXStoreOrderDto storeOrderDto,Integer userId) {
        try {
            OrderStatus orderStatus = new OrderStatus();
            StoreOrder storeOrder = storeOrderDto.getStoreOrder();
            storeOrder.setUserId(userId);
            Date date = new Date();
            storeOrder.setCreateTime(date);
            orderStatus.setChangeTime(date);
            orderStatus.setChangeMessage(returnStatusMessage(1));
            storeOrder.setStatus(StatusEnum.getEnumsByCode(1));
            orderStatus.setChangeType(1);
            String dd = new SimpleDateFormat("dd").format(date);
            Long increment = stringRedisTemplate.opsForValue().increment(RedisKey.ORDER_NUMBER+storeOrder.getStoreId(), 1);
            if (increment == 1) {
                Calendar cal = Calendar.getInstance();
                int i = 86400 - cal.get(Calendar.SECOND) - cal.get(Calendar.MINUTE) * 60 - cal.get(Calendar.HOUR_OF_DAY) * 60 * 60;
                stringRedisTemplate.expire(RedisKey.ORDER_NUMBER, i, TimeUnit.SECONDS);
            }
            String number = dd + "-" + increment;
            storeOrder.setNumber(number);
            int insert = storeOrderMapper.insert(storeOrder);
            orderStatus.setOrderId(storeOrder.getOrderId());
            orderStatusMapper.insert(orderStatus);
            Integer result = 0;
            if (insert != 0) {
                for (OrderCommodity o : storeOrderDto.getOrderCommodityList()) {
                    o.setOrderId(storeOrder.getOrderId());
                    int insert1 = orderCommodityMapper.insert(o);
                    result += insert1;
                    CommodityDetails commodityDetails = commodityDetailsMapper.selectById(o.getCommodityDetailsId());
                    Integer nowStock = commodityDetails.getStock() - o.getQuantity();
                    if(nowStock < 0){
                        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                        return new Result().setCode(2).setMessage("库存不足，请联系商家！");
                    }else{
                        commodityDetails.setStock(nowStock);
                        commodityDetailsMapper.updateById(commodityDetails);
                    }
                }
            }
            if(insert >0 && result >0){
                return new Result().setCode(0).setMessage("下单成功！").setData(null);
            }else{
                throw new RuntimeException("下单失败");
            }
        }catch (Exception e) {
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return new Result().setCode(2).setMessage("下单失败！");
        }
    }

    @Override
    public Result getAllOrder(Integer current, Integer isNowDay,Integer userId) {
        Integer size = 5;
        current = size*(current-1);
        List<StoreOrderDto> allOrderList = storeOrderMapper.getAllOrderList(current, size, isNowDay,userId);
        return new Result().setCode(0).setMessage("获取成功！").setData(allOrderList);
    }

    @Override
    public void CompleteOrderTimingTask() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -2);
        Date expirationTime = calendar.getTime();
        List<CompleteOrderTimingTaskDTO> completeOrderTimingTaskDTOS = storeOrderMapper.selectCompleteOrderTimingTask();
        for(CompleteOrderTimingTaskDTO c : completeOrderTimingTaskDTOS){
            Date changeTime = c.getOrderStatusList().get(c.getOrderStatusList().size() - 1).getChangeTime();
//            System.out.println(changeTime + "过期："+changeTime.before(expirationTime));
            if(changeTime.before(expirationTime)){
                StoreOrder storeOrder = new StoreOrder();
                storeOrder.setOrderId(c.getOrderId());
                storeOrder.setStatus(StatusEnum.TransactionCompletion);
                OrderStatus orderStatus = new OrderStatus();
                orderStatus.setOrderId(c.getOrderId());
                orderStatus.setChangeType(5);
                orderStatus.setChangeTime(new Date());
                orderStatus.setChangeMessage("订单完成超过48小时，自动确定");
                storeOrderMapper.updateById(storeOrder);
                orderStatusMapper.insert(orderStatus);
            }
        }
    }

    @Override
    public void RefundOrderTimingTask() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DATE, -2);
        Date expirationTime = calendar.getTime();
        List<CompleteOrderTimingTaskDTO> completeOrderTimingTaskDTOS = storeOrderMapper.selectRefundOrderTimingTask();
        for(CompleteOrderTimingTaskDTO c : completeOrderTimingTaskDTOS){
            Date changeTime = c.getOrderStatusList().get(c.getOrderStatusList().size() - 1).getChangeTime();
//            System.out.println(changeTime + "过期："+changeTime.before(expirationTime));
            if(changeTime.before(expirationTime)){
                StoreOrder storeOrder = new StoreOrder();
                storeOrder.setOrderId(c.getOrderId());
                storeOrder.setStatus(StatusEnum.Refunded);
                OrderStatus orderStatus = new OrderStatus();
                orderStatus.setOrderId(c.getOrderId());
                orderStatus.setChangeType(-2);
                orderStatus.setChangeTime(new Date());
                orderStatus.setChangeMessage("订单退款超过48小时未操作，自动退款！");
                storeOrderMapper.updateById(storeOrder);
                orderStatusMapper.insert(orderStatus);
            }
        }
    }
}




